/**
 * @Company: 云南奇讯科技有限公司
 * @Author: yxf
 * @Description:
 * @Version: 1.0.0
 * @Date: 2021/11/3 9:46
 */

package service

import (
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/gogf/gf/v2/util/grand"
	commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
	"github.com/tiger1103/gfast/v3/internal/app/plugins/sms/consts"
	"github.com/tiger1103/gfast/v3/internal/app/plugins/sms/dao"
	"github.com/tiger1103/gfast/v3/internal/app/plugins/sms/model"
	"github.com/tiger1103/gfast/v3/internal/app/plugins/sms/model/do"
	"time"
)

const (
	PrefixMobile = consts.CachePrefix + "mobileCaptcha_"
)

type smsService struct {
}

var Sms = new(smsService)

// CreateVerifyCode 创建手机验证码
func (s *smsService) CreateVerifyCode(ctx context.Context, mobile string) (captcha int, err error) {
	key := PrefixMobile + mobile
	cache := commonService.Cache()
	if cache.Contains(ctx, key+"_countdown") {
		return 0, errors.New("请稍后再试")
	}
	captcha = grand.N(1000, 9999)
	// 限制60秒内只能发一次。
	cache.Set(ctx, key+"_countdown", captcha, 60*time.Second)
	cache.Set(ctx, key, captcha, 10*60*time.Second)
	return
}

// CheckVerifyCode 验证手机验证码
func (s *smsService) CheckVerifyCode(ctx context.Context, mobile, verifyCode string) (err error) {
	key := PrefixMobile + mobile
	cache := commonService.Cache()
	if !cache.Contains(ctx, key) {
		return errors.New("验证码已过期")
	}
	value := cache.Get(ctx, key)
	if value.String() != verifyCode {
		return errors.New("请输入正确的验证码")
	} else {
		// 只有正确的时候才能移除验证码
		cache.Remove(ctx, key)
		return
	}
}

func (s *smsService) RegisterSmsService(ctx context.Context) error {
	err := s.PublishSmsPluginConfigChangeEvent(ctx)
	return err
}

// PublishSmsPluginConfigChangeEvent 发布短信配置变更事件
func (s *smsService) PublishSmsPluginConfigChangeEvent(ctx context.Context) (err error) {
	var smsPluginInfo *model.PluginSmsConfigInfoRes
	err = dao.PluginSmsConfig.Ctx(ctx).Where("status", 1).Scan(&smsPluginInfo)
	if err != nil {
		return
	}
	if smsPluginInfo == nil {
		err = errors.New("未获取到短信配置信息")
		return
	}
	commonService.EventBus().Publish("sms_plugin:registerService", smsPluginInfo.SmsType)
	return
}

// WriteLog 保存发送日志
func (s *smsService) WriteLog(ctx context.Context, arg *model.ClientArg) error {
	_, err := dao.PluginSmsLog.Ctx(ctx).Insert(do.PluginSmsLog{
		SmsType:    arg.SmsType,
		MsgType:    arg.MsgType,
		Templateid: arg.TemplateId,
		Mobiles:    gconv.String(arg.Mobiles),
		Params:     gconv.String(arg.Params),
		Result:     arg.Result,
	})
	if err != nil {
		return errors.New(fmt.Sprintf("平台:%s,类型:%s,记录日志错误: %s\n", arg.SmsType, arg.TemplateId, err.Error()))
	}
	return nil
}
